home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 1.iso
/
toolbox
/
src
/
exampleCode
/
opengl
/
extensions
/
samples
/
ConvSharpenBlur.c
next >
Wrap
C/C++ Source or Header
|
1996-11-11
|
9KB
|
324 lines
/*
* Copyright (c) 1994 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee,
* provided that (i) the above copyright notices and this permission
* notice appear in all copies of the software and related documentation,
* and (ii) the name of Silicon Graphics may not be used in any
* advertising or publicity relating to the software without the specific,
* prior written permission of Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL,
* INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
/*
* ConvSharpenBlur - Demonstrate sharpenening and bluring of an image using
* convolution.
*
* Keys:
* Home - Set sharpness to 0 (neutral)
* Up/Down - increase/decrease sharpness by 0.25
* s - toggle histogram display
* m - print min max value.
* i - print sharpness value
* x/y - toggle x/y mirroring of image
* h/? - help
* Esc - quit
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <GL/glx.h>
#include <X11/keysym.h>
#include "xwindow.h"
#define RECT_SIZE 512
#define WIN_SIZE 1.5*RECT_SIZE
#define XORG 0.25*RECT_SIZE
#define YORG 0.25*RECT_SIZE
GLubyte buf1[RECT_SIZE][RECT_SIZE][3];
static float sharpness = 0;
static GLboolean doHistogram = GL_FALSE;
GLint curPos[2] = {XORG, YORG};
Display *dpy;
Window win;
GLint xFlip = 1, yFlip = 1;
void render(void);
void getMinMax(void);
#if defined(GL_EXT_convolution) && defined(GL_EXT_histogram)
void
main(int argc, char* argv[])
{
int visualAttr[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 1, None};
GLboolean done = GL_FALSE;
GLXContext ctx;
int yi, xi;
const GLubyte *extensionsString;
if (argc > 1) {
fprintf(stderr, "usage: %s [-h for help]\n", argv[0]);
fprintf(stderr,
"\tInteractively, `h/?' keys provide description of\
interface\n");
exit (argv[1][0] == '-' && argv[1][1] == 'h' ?
EXIT_SUCCESS : EXIT_FAILURE);
}
createWindowAndContext(&dpy, &win, &ctx, 100, 100, WIN_SIZE, WIN_SIZE,
GL_TRUE, NULL, visualAttr, "Convolve");
extensionsString = glGetString(GL_EXTENSIONS);
/*
* Check for convolution extension.
*/
if (extensionsString == NULL ||
!strstr((const char *) extensionsString, "EXT_convolution")) {
/*
* HACK - Convolution is not formally advertised. Try using it anyhow.
*/
glDisable(GL_CONVOLUTION_2D_EXT);
if (glGetError() != GL_NO_ERROR) {
fprintf(stderr, "Sorry convolution is not supported by the renderer\n");
exit(EXIT_FAILURE);
} else
fprintf(stderr, "Assuming EXT_convolution supported but not\
advertised\n");
}
/*
* Check for histogram extension.
*/
if (!strstr((const char *) extensionsString, "EXT_histogram")) {
/*
* HACK - Histogram is not formally advertised. Try getting it anyhow.
*/
glDisable(GL_HISTOGRAM_EXT);
if (glGetError() != GL_NO_ERROR) {
fprintf(stderr, "Sorry histogram is not supported in the renderer\n");
exit(EXIT_FAILURE);
} else
fprintf(stderr, "Assuming EXT_histogram supported but not\
advertised\n");
}
/* Create Image */
for (yi = 0; yi < RECT_SIZE; yi++)
for (xi = 0; xi < RECT_SIZE; xi++) {
buf1[yi][xi][0] = xi & 0xff;
buf1[yi][xi][1] = (xi^yi) & 0xff;
buf1[yi][xi][2] = yi & 0xff;
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ROW_LENGTH, RECT_SIZE);
glViewport(0, 0, WIN_SIZE, WIN_SIZE);
glLoadIdentity();
glOrtho(0, WIN_SIZE, 0, WIN_SIZE, -1, 1);
glClearColor(0.1, 0.4, 0.8, 0.);
/*
* Select histogram and minmax statistic to RGBA (even though we're only
* going to read RGB). As they are not used together both are "sink"ed
* (no drawing to frame buffer). If histogram and minmax were used
* together, then we would only sink minmax (comes last).
*/
glMinmaxEXT(GL_MINMAX_EXT, GL_RGBA, GL_TRUE);
glHistogramEXT(GL_HISTOGRAM_EXT, 4096, GL_RGBA, GL_TRUE);
while (!done) {
XEvent event;
XNextEvent(dpy, &event);
switch (event.type) {
case KeyPress:
switch (XLookupKeysym(&event.xkey, 0)) {
case XK_Escape:
done = GL_TRUE;
break;
case XK_i:
case XK_I:
printf("Sharpeness is %g\n",sharpness);
break;
case XK_m:
getMinMax();
break;
case XK_s:
doHistogram = !doHistogram;
printf("Histogram is %s\n", doHistogram ? "ON" : "OFF");
render();
break;
case XK_x:
xFlip *= -1;
curPos[0] -= RECT_SIZE * xFlip;
render();
break;
case XK_y:
yFlip *= -1;
curPos[1] -= RECT_SIZE * yFlip;
render();
break;
case XK_Up:
if (sharpness < 10) {
sharpness += 0.25;
render();
}
break;
case XK_Home:
sharpness = 0;
render();
break;
case XK_Down:
if (sharpness > -10) {
sharpness -= 0.25;
render();
}
break;
case XK_h:
case XK_H:
case XK_question:
printf("Keys:\tHome - Set sharpness to 0 (neutral)\n");
printf("\tUp/Down - increase/decrease sharpness\n");
printf("\ts - toggle histogram display\n");
printf("\tm - print min max value.\n");
printf("\ti - print sharpness value\n");
printf("\tx/y - toggle x/y mirroring of image\n");
printf("\th/? - help\n");
printf("\tEsc - quit\n");
break;
}
break;
case DestroyNotify:
done = GL_TRUE;
break;
case Expose:
render();
break;
}
}
}
/*
* Define the convolution filter.
* 0 means no filtering.
* Positive/Negative mean sharpen/blur.
* When filtering, a separable radially symetric 5x5 kernel is used.
*/
void
setFilter(float sharpness /* [-10..10] */)
{
float row[5];
float k0, k1, kscale;
if (sharpness != 0.0) {
if (sharpness < 0.0) {
k0 = 0.15 - sharpness * 0.285;
k1 = -0.6 - sharpness * 0.360;
} else {
k0 = 0.15 - sharpness * 0.045;
k1 = -0.6 - sharpness * 0.045;
}
kscale = 1/(2*k0 + 2*k1 + 3);
row[0] = row[4] = k0 * kscale;
row[1] = row[3] = k1 * kscale;
row[2] = 3 * kscale;
glSeparableFilter2DEXT(GL_SEPARABLE_2D_EXT, GL_LUMINANCE,
5, 5, GL_LUMINANCE, GL_FLOAT, row, row);
glEnable(GL_SEPARABLE_2D_EXT);
} else
glDisable(GL_SEPARABLE_2D_EXT);
}
/*
* Retrieve and print the image min and max component values.
*/
void
getMinMax()
{
GLfloat minmax[6];
glEnable(GL_MINMAX_EXT);
glResetMinmaxEXT(GL_MINMAX_EXT);
glReadBuffer(GL_FRONT);
glCopyPixels(XORG, YORG, RECT_SIZE, RECT_SIZE, GL_COLOR);
glReadBuffer(GL_BACK);
glGetMinmaxEXT(GL_MINMAX_EXT, GL_TRUE, /* Reset */
GL_RGB, GL_FLOAT, minmax);
printf("Min (%g %g %g) Max (%g %g %g)\n",
minmax[0], minmax[1], minmax[2],
minmax[3], minmax[4], minmax[5]);
glDisable(GL_MINMAX_EXT);
}
/*
* Retrieve and draw the image histogram.
*/
void
getHistogram(void)
{
GLfloat hist[3*4096], *histp;
static const float colors[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
int i,j;
glDisable(GL_SEPARABLE_2D_EXT);
glEnable(GL_HISTOGRAM_EXT);
glResetHistogramEXT(GL_HISTOGRAM_EXT);
glCopyPixels(XORG, YORG, RECT_SIZE, RECT_SIZE, GL_COLOR);
glGetHistogramEXT(GL_HISTOGRAM_EXT, GL_TRUE, /* reset */
GL_RGB, GL_FLOAT, hist);
glDisable(GL_HISTOGRAM_EXT);
for (j = 0; j < 3; j++) {
glColor3fv(&colors[3*j]);
histp = &hist[j];
glBegin(GL_LINE_STRIP);
for (i = 0; i < 4096; i++, histp += 3) {
glVertex2f(10 + i * ((GLfloat) WIN_SIZE - 20)/4096,
50 + (WIN_SIZE - 100)/3.0 * (j +
50**histp/(RECT_SIZE*RECT_SIZE)));
}
glEnd();
}
}
/*
* Render a single frame.
*/
void
render()
{
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_SEPARABLE_2D_EXT);
glPixelZoom(1, 1);
glRasterPos2i(XORG, YORG);
glDrawPixels(RECT_SIZE, RECT_SIZE, GL_RGB, GL_UNSIGNED_BYTE, buf1);
glPixelZoom(xFlip, yFlip);
glRasterPos2iv(curPos);
setFilter(sharpness);
glCopyPixels(XORG, YORG, RECT_SIZE, RECT_SIZE, GL_COLOR);
if (doHistogram)
getHistogram();
glXSwapBuffers(dpy, win);
}
#else /* either histogram on convolution is not part of the library */
/* Generate a compiler error with a message */
Sorry CONVOLUTION OR HISTOGRAM is not supported by the library.
#endif